package makabakaquestionnaire.zutsoftware.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import makabakaquestionnaire.zutsoftware.constant.ProjectRedisKeyConstants;
import makabakaquestionnaire.zutsoftware.constant.Result;
import makabakaquestionnaire.zutsoftware.entity.ProjectItem;
import makabakaquestionnaire.zutsoftware.entity.ProjectResult;
import makabakaquestionnaire.zutsoftware.entity.ProjectSetting;
import makabakaquestionnaire.zutsoftware.entity.UserProject;
import makabakaquestionnaire.zutsoftware.entity.request.QueryResultRequest;
import makabakaquestionnaire.zutsoftware.entity.vo.AntVCharts;
import makabakaquestionnaire.zutsoftware.framework.email.EmailService;
import makabakaquestionnaire.zutsoftware.framework.email.SendEmailModel;
import makabakaquestionnaire.zutsoftware.service.impl.ProjectItemServiceImpl;
import makabakaquestionnaire.zutsoftware.service.impl.ProjectResultServiceImpl;
import makabakaquestionnaire.zutsoftware.service.impl.ProjectSettingServiceImpl;
import makabakaquestionnaire.zutsoftware.service.impl.UserProjectServiceImpl;
import makabakaquestionnaire.zutsoftware.utils.HttpUtils;
import makabakaquestionnaire.zutsoftware.utils.redis.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@Api(tags = "问题填写结果接口")
@RestController
@RequestMapping("project/result")
public class ProjectResultController {
    private RedisUtils redisUtils;
    private EmailService emailService;
    ProjectResultServiceImpl projectResultService;
    UserProjectServiceImpl userProjectService;
    ProjectSettingServiceImpl projectSettingService;
    ProjectItemServiceImpl projectItemService;

    @Autowired
    public void setProjectItemService(ProjectItemServiceImpl projectItemService) {
        this.projectItemService = projectItemService;
    }

    @Autowired
    public void setProjectResultService(ProjectResultServiceImpl projectResultService) {
        this.projectResultService = projectResultService;
    }

    @Autowired
    public void setEmailService(EmailService emailService) {
        this.emailService = emailService;
    }

    @Autowired
    public void setUserProjectService(UserProjectServiceImpl userProjectService) {
        this.userProjectService = userProjectService;
    }

    @Autowired
    public void setProjectSettingService(ProjectSettingServiceImpl projectSettingService) {
        this.projectSettingService = projectSettingService;
    }

    @Autowired
    public void setRedisUtils(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;
    }

    @ApiOperation("得到填写结果的分页")
    @PostMapping("/page")
    public Result queryResultByRequest(@RequestBody QueryResultRequest queryResultRequest) {
        return Result.success(projectResultService.queryProjectByRequest(queryResultRequest));
    }

    @ApiOperation("保存填写结果")
    @PostMapping("/save")
    public Result saveResult(@RequestBody ProjectResult projectResult, HttpServletRequest request) {
        String ip = HttpUtils.getIpAddr(request);
        /**
         * 根据Setting设置的起始时间结束时间、收集数量、每人填写次数等判断
         * 如果不满足条件返回Result<null,"msg"></>
         * 满足条件返回Result<projectSetting>
         */
        Result<ProjectSetting> projectSettingResult = projectSettingService.getUserProjectSettingStatus(projectResult.getProjectKey(), ip);
        if (projectSettingResult.getMsg() != null) {
            return Result.failed(projectSettingResult.getMsg());
        }
        projectResult.setSubmitRequestIp(ip);
        String now = DateUtil.now();
        Date date = DateUtil.parse(now);   //转为date格式
        projectResult.setCreateTime(date);
        projectResult.setUpdateTime(date);
        String proKey = projectResult.getProjectKey();
        if (!redisUtils.exists(
                StrUtil.format(ProjectRedisKeyConstants.PROJECT_RESULT_NUMBER, proKey))
        ) {
            redisUtils.set(StrUtil.format(ProjectRedisKeyConstants.PROJECT_RESULT_NUMBER, proKey), projectResultService.getResultMaxNum(proKey));
        }
        projectResult.setSerialNumber(
                redisUtils.incr(StrUtil.format(ProjectRedisKeyConstants.PROJECT_RESULT_NUMBER, proKey), 1L)
        );
        /**
         * 通过线程池执行器，在EmailServiceImpl的异步方法中执行发送邮件请求
         */
        sendEmailNotify(projectSettingResult.getData());
        boolean save = projectResultService.saveProjectResult(projectResult);

        return Result.success(projectResult, "填写" + save);
    }

    public void sendEmailNotify(ProjectSetting projectSetting) {
        if (ObjectUtil.isEmpty(projectSetting)) {
            return;
        }
        if (projectSetting.getNewWriteNotifyEmail() != null) {
            UserProject userProject = userProjectService.queryProjectByProKey(projectSetting.getProjectKey());
            SendEmailModel model = new SendEmailModel();
            model.setReceiver(projectSetting.getNewWriteNotifyEmail());
            String textBody = String.format("您创建的问卷%s收到反馈,请前往系统中查看", userProject.getProjectName());
            model.setTextBody(textBody);
            model.setTitle("您的问卷新回复通知");
            emailService.sendEmail(model);
        }
    }

    /**
     * 返回要统计的数据
     */
    @GetMapping("/statistics/{ProKey}")
    public Result Statistics(@PathVariable String ProKey) {
        QueryResultRequest queryResultRequest = new QueryResultRequest();
        queryResultRequest.setProjectKey(ProKey);
        List<ProjectResult> list = projectResultService.selectProjectResultList(queryResultRequest);
        ConcurrentHashMap<String, Object> results = new ConcurrentHashMap<>();
        for (int i = 0; i < list.size(); i++) {
            ProjectResult projectResult = (ProjectResult) list.get(i);
            for (String s : projectResult.getProcessData().keySet()) {
                //文本题
                if (projectResult.getOriginalData().get(s) instanceof String) {

                    List<AntVCharts> charts;
                    if (results.get(s) == null) {
                        charts = new ArrayList<>();
                    } else {
                        charts = (List) results.get(s);
                    }
                    Boolean flag = false;
                    for (int i1 = 0; i1 < charts.size(); i1++) {
                        if (charts.get(i1).getVarchar().equals(projectResult.getProcessData().get(s).toString())) {
                            charts.get(i1).setValue(charts.get(i1).getValue() + 1);
                            flag = true;
                            break;
                        }
                    }
                    if (flag == false) {
                        AntVCharts text = new AntVCharts();
                        text.setVarchar(projectResult.getProcessData().get(s).toString());
                        text.setValue(text.getValue() + 1);
                        charts.add(text);
                        results.put(s, charts);
                    }

                } else {
                    //选项
                    HashMap<String, Integer> option;
                    if (results.get(s) == null) {
                        option = new HashMap<String, Integer>();
                    } else {
                        option = (HashMap) results.get(s);
                    }
                    String key = projectResult.getProcessData().get(s).toString();
                    option.put(key, option.getOrDefault(key, 0) + 1);
                    results.put(s, option);
                }
            }
        }
        // int num=1;
        HashMap<String, Object> ans = new HashMap();
        for (String s : results.keySet()) {
            Long id = Long.parseLong(s.substring(5));
            ProjectItem item = projectItemService.queryItemById(id);
            if (item == null) continue;
            if (results.get(s) instanceof HashMap) {
                HashMap<String, Integer> option = (HashMap) results.get(s);
                if (item.getExtend() == null) {     //评分题无Extend
                    Integer sum = 0;//总分
                    Integer num = 0;//出现次数
                    for (String key : option.keySet()) {
                        num += option.get(key);
                        sum += option.get(key) * Integer.parseInt(key);
                    }
                    List<AntVCharts> score=new ArrayList<>();
                    Double reverse=(sum / num) * 20.0;
                    Integer value=reverse.intValue();
                    score.add(new AntVCharts("评分",value,null));
                    ans.put(item.getLabel(), score);
                } else if (item.getExtend().get("options") != null) {     //单选题
                    JSONArray jsonArray = (JSONArray) item.getExtend().get("options");
                    List<AntVCharts> charts = new ArrayList<>();
                    float sum=0;   //计算百分比
                    for (String s1 : option.keySet()) {
                        sum+=option.get(s1);
                    }
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                        String label = jsonObject.get("label").toString();
//                        option.put(label, option.getOrDefault(label, 0));
                        float precent = (float)(Math.round(option.getOrDefault(label,0)/sum*10000))/100;   //改为百分比并且小数点取两位
                        charts.add(new AntVCharts(label, option.getOrDefault(label,0), null,precent));
                    }
                    results.put(s, charts);
                    ans.put(item.getLabel(), charts);
                }
            } else {
                ans.put(item.getLabel(), results.get(s));
            }
        }
        return Result.success(ans);
    }

}
